package com.nuc.zyt.day02.Enum;

import java.math.BigDecimal;

/**
 * @ClassName MemberDemo
 * @Description TODO
 * @Author 耀酱
 * @Date 2023/5/16 13:15
 * @Version 1.0
 */

/**
 * 但如果采用策略枚举的方式，把易变动的逻辑抽取出来共同维护就会方便很多。
 *
 * 设计模式中有个说法：越抽象越稳定，越具体越不稳定，所以提倡面向抽象编程。设计模式的目的不是消除变化，而是隔离变化。在软件工程中，
 * 变化的代码就像房间里一只活蹦乱跳的兔子，你并不能让它绝对安静（不要奢望需求永不变更），但可以准备一个笼子把它隔离起来，从而达到整体的稳定。
 */
    public class MemberDemo {

        public static void main(String[] args) {

            User user = new User(1L, "耀酱", MemberEnum.GOLD_MEMBER.getType());
            BigDecimal productPrice = new BigDecimal("1000");
            BigDecimal discountedPrice = calculateFinalPrice(productPrice, user.getMemberType());
            System.out.println(discountedPrice);
        }

        /**
         * 根据会员身份返回折扣后的商品价格
         *
         * @param originPrice
         * @param
         * @return
         */
        public static BigDecimal calculateFinalPrice(BigDecimal originPrice, Integer type) {
            return MemberEnum.getEnumByType(type).calculateFinalPrice(originPrice);
        }
    }


    class User {
        private Long id;
        private String name;
        /**
         * 会员身份
         * 1：黄金会员，6折优惠
         * 2：白银会员，7折优惠
         * 3：青铜会员，8折优惠
         */
        private Integer memberType;

        public User(Long id, String name, Integer memberType){
            this.id = id;
            this.name = name;
            this.memberType = memberType;
        }

        public Integer getMemberType(){
            return memberType;
        }
    }

    enum MemberEnum {
        // ---------- 把这几个枚举当做本应该在外面实现的MemberEnum子类，不要看成MemberEnum内部的 ----------
        GOLD_MEMBER(1, "黄金会员") {
            @Override
            public BigDecimal calculateFinalPrice(BigDecimal originPrice) {
                return originPrice.multiply(new BigDecimal(("0.6")));
            }
        },

        SILVER_MEMBER(2, "白银会员") {
            @Override
            public BigDecimal calculateFinalPrice(BigDecimal originPrice) {
                return originPrice.multiply(new BigDecimal(("0.7")));
            }
        },

        BRONZE_MEMBER(3, "青铜会员") {
            @Override
            public BigDecimal calculateFinalPrice(BigDecimal originPrice) {
                return originPrice.multiply(new BigDecimal(("0.8")));
            }
        },
        ;

        // ---------- 下面才是MemberEnum类的定义 ---------
        private final Integer type;
        private final String desc;

        MemberEnum(Integer type, String desc) {
            this.type = type;
            this.desc = desc;
        }

        /**
         * 定义抽象方法，留给子类实现
         *
         * @param originPrice
         * @return
         */
        protected abstract BigDecimal calculateFinalPrice(BigDecimal originPrice);

        public Integer getType() {
            return type;
        }

        public String getDesc() {
            return desc;
        }

        public static MemberEnum getEnumByType(Integer type) {
            MemberEnum[] values = MemberEnum.values(); // 枚举类获取所有枚举子类方法
            for (MemberEnum memberEnum : values) {
                if (memberEnum.getType().equals(type)) {
                    return memberEnum;
                }
            }
            throw new IllegalArgumentException("Invalid Enum type:" + type);
        }
    }

